package service

import (
	context "context"
	"go-locks/optimistic-lock/db"
	"go-locks/optimistic-lock/model"
	"go-locks/optimistic-lock/proto"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
	"log"
)

type Server struct{}

func (s Server) SellStock(ctx context.Context, request *proto.StockRequest) (*emptypb.Empty, error) {
	tx := db.DB.Begin()
	for _, info := range request.StockInfos {
		var stock model.Stock
		for {
			if result := db.DB.Where(&model.Stock{Goods: info.GoodsId}).First(&stock); result.RowsAffected == 0 {
				return nil, status.Error(codes.NotFound, "商品信息不存在")
			}
			if stock.Stocks < info.Num {
				// 库存不足 回滚事务
				tx.Rollback()
				return nil, status.Error(codes.ResourceExhausted, "库存不足")
			}
			stock.Stocks -= info.Num
			if result := tx.Model(&model.Stock{}).Select("Stocks", "Version").
				Where("goods = ? AND version = ?", info.GoodsId, stock.Version).Updates(&model.Stock{Stocks: stock.Stocks, Version: stock.Version + 1}); result.RowsAffected == 0 {
				// version 字段冲突;扣减失败
				log.Println("库存扣减失败;重试")
			} else {
				// 库存扣减成功
				log.Println("库存扣减成功")
				break
			}
		}
	}
	tx.Commit()
	return &emptypb.Empty{}, nil
}
